/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { useCallback, useState, useEffect, useMemo } from "react";
import { Typography, Form, Row, Col, Button, Input, Radio, message, Popconfirm } from "antd";
import { connect } from "dva";
import { spliceURL } from "@/utils/patterns";
import InputWithHttps from "../../../components/InputWithHttps";
import BuiltInMenuModal from "./BuiltInMenuModal";
import BuildInMenuSelect from "./BuildInMenuSelect";
import SettingPublish from "./SettingPublish";
import styles from "./MenuSetting.less";

const { Title, Text } = Typography;
const FormItem = Form.Item;
const RadioGroup = Radio.Group;

const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 4 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 16 },
  },
};
const tailFormItemLayout = {
  wrapperCol: {
    xs: {
      span: 24,
      offset: 0,
    },
    sm: {
      span: 16,
      offset: 4,
    },
  },
};

const helps = {
  view: "用户点击该菜单跳转以下链接",
  miniprogram: "用户点击该菜单跳转以下小程序",
  click: "用户点击该菜单会在公众号会话框发送关键词回复对应的文本",
};

const formItemMap = (channel, disabled) => {
  switch (channel) {
    case "view":
      return [
        {
          label: "页面地址",
          paramKey: "url",
          rules: [
            {
              required: !disabled,
              message: "缺少页面地址",
            },
          ],
          placeholder: disabled ? "已选择系统链接无需再次输入" : "请输入页面地址",
          disabled,
        },
      ];
    case "miniprogram":
      return [
        {
          label: "小程序APPID",
          paramKey: "appid",
          rules: [
            {
              required: true,
              message: "缺少小程序APPID",
            },
          ],
          placeholder: "请输入小程序APPID",
          disabled,
        },
        {
          label: "页面地址",
          paramKey: "pagepath",
          rules: [
            {
              required: true,
              message: "缺少小程序页面地址",
            },
          ],
          placeholder: "请输入小程序页面地址",
          disabled,
        },
      ];
    case "click":
      return [
        {
          label: "输入关键词",
          paramKey: "key_word_content",
          rules: [
            {
              required: true,
              message: "缺少关键词",
            },
          ],
          placeholder: "请输入关键词",
          disabled,
        },
      ];

    default:
      return [];
  }
};

const MenuSetting = ({
  dispatch,
  form,
  showMenuSetting,
  selectMenuData,
  currentMiniAppPlatform = {},
  officialMenuMap,
  miniProgramMenuMap,
  platformList = {},
}) => {
  const { validateFields, getFieldDecorator, setFieldsValue, resetFields } = form;
  const {
    menuKey: selectMenuKey,
    name,
    url,
    appid,
    page: selectMenuPage,
    type,
    systemMenuName,
    systemMenuKey,
    sub_button = [],
  } = selectMenuData;
  const { appid: currentMiniAppId } = currentMiniAppPlatform;
  const { weixin = {} } = platformList;
  const { platform } = weixin;

  const [channel, setChannel] = useState("view");
  const [visible, setVisible] = useState(false);
  const [hasSelectSystemMenu, setHasSelectSystemMenu] = useState(false);
  const [tcjsOpened, setTcjsOpened] = useState(true);
  const [buildInMenus, setBuildInMenus] = useState({});

  // 是否是主菜单
  const isMainMenu = selectMenuKey && selectMenuKey.length == 1;
  // 主菜单是否设置了子菜单，只有子菜单有type字段，才说明设置了子菜单
  const hasSetSubMenu = isMainMenu && sub_button.filter(i => i.type).length > 0;

  const onRadioChange = useCallback(
    e => {
      const { value } = e.target;
      setChannel(value);
      setBuildInMenus({});
      resetFields(["url", "page"]);
      setHasSelectSystemMenu(false);
    },
    [resetFields]
  );

  const onSystemMenuClick = useCallback(
    (value = {}, platform) => {
      const { name: systemMenuName, page, key } = value;

      dispatch({
        type: "wxSettings/checkHasOpenTCJS",
        payload: {
          platform,
          selectMenuKey: key,
        },
      }).then(opened => {
        setTcjsOpened(opened);
        if (opened) {
          setBuildInMenus({
            ...(value || {}),
            systemMenuKey: key,
          });
          setHasSelectSystemMenu(true);
          setFieldsValue({
            url: undefined,
            pagepath: page,
            appid: currentMiniAppId,
          });
        } else {
          setBuildInMenus({
            name: systemMenuName,
          });
          setHasSelectSystemMenu(false);
        }
      });
    },
    [setFieldsValue, dispatch, currentMiniAppId]
  );

  const onClose = useCallback(
    () => {
      dispatch({
        type: "wxSettings/save",
        payload: {
          showMenuSetting: false,
          selectMenuData: {},
        },
      });
    },
    [dispatch]
  );

  const onSubmit = useCallback(
    () => {
      validateFields((err, values) => {
        if (err) return;
        const isMiniProgram = values.type === "miniprogram";
        // 更新本地菜单列表的数据
        dispatch({
          type: "wxSettings/updateMenuList",
          payload: {
            changedMenu: {
              ...values,
              ...(isMiniProgram ? { url: "https://kuaidihelp.com" } : {}),// 小程序备用链接
              systemMenuKey: buildInMenus.systemMenuKey,
            },
          },
        }).then(() => {
          message.success("保存成功");
          onClose();
        });
      });
    },
    [validateFields, dispatch, onClose, buildInMenus]
  );

  const onRemoveSelectMenu = useCallback(
    () => {
      setBuildInMenus({});
      setTcjsOpened(true);
      setHasSelectSystemMenu(false);
      resetFields(["url"]);
    },
    [resetFields]
  );

  const nameRules = useMemo(
    () => {
      if (isMainMenu) {
        return {
          pattern: /^[\u4E00-\u9FA5A-Za-z0-9]{0,8}$/,
          message: "仅支持中英文和数字，字数不超过4个汉字或8个字母",
        };
      } else {
        return {
          pattern: /^[\u4E00-\u9FA5A-Za-z0-9]{0,16}$/,
          message: "仅支持中英文和数字，字数不超过8个汉字或16个字母",
        };
      }
    },
    [isMainMenu]
  );

  const onDelete = menuKey => {
    dispatch({
      type: "wxSettings/updateMenuList",
      payload: {
        changedMenu: {
          name: menuKey,
        },
      },
    }).then(() => {
      message.success("删除成功");
      onClose();
    });
  };

  useEffect(
    () => {
      dispatch({
        type: "wxSettings/getOfficialMenu",
      });
      dispatch({
        type: "wxSettings/getMiniProgramMenu",
      });

      return () => {
        resetFields();
        onClose();
        onRemoveSelectMenu();
      };
    },
    [dispatch, resetFields, onClose, onRemoveSelectMenu]
  );

  useEffect(
    () => {
      setChannel(type || "view");
    },
    [type]
  );

  useEffect(
    () => {
      // 如果菜单的链接与系统链接匹配，则显示系统链接
      let systemMenu = {};
      if (
        miniProgramMenuMap[selectMenuPage] ||
        officialMenuMap[url] ||
        officialMenuMap[systemMenuKey]
      ) {
        setHasSelectSystemMenu(true);
        if (type === "view") {
          systemMenu = {
            name: systemMenuName || officialMenuMap[url] || officialMenuMap[systemMenuKey],
            url,
          };
        } else if (type === "miniprogram") {
          systemMenu = {
            name: systemMenuName || miniProgramMenuMap[selectMenuPage],
            url,
            appid,
            page: selectMenuPage,
          };
        }
      } else {
        setHasSelectSystemMenu(false);
      }
      setBuildInMenus(systemMenu);
    },
    [name, url, appid, selectMenuPage, systemMenuName, systemMenuKey, type]
  );

  return (
    <div className={styles.formWrapper}>
      {showMenuSetting ? (
        <>
          <Row>
            <Col>
              <Title level={3}>{`请设置${isMainMenu ? "主" : "子"}菜单`}</Title>
            </Col>
          </Row>
          <Form {...formItemLayout}>
            <Form.Item label={`${isMainMenu ? "主" : "子"}菜单名称`} help={nameRules.message}>
              {getFieldDecorator("name", {
                rules: [
                  {
                    required: true,
                    message: `缺少${isMainMenu ? "主" : "子"}菜单名称`,
                  },
                  nameRules,
                ],
              })(<Input placeholder="请输入菜单名称" allowClear />)}
            </Form.Item>
            {!hasSetSubMenu && (
              <>
                <FormItem label="选择渠道" help={helps[channel]}>
                  {getFieldDecorator("type", {
                    initialValue: channel,
                  })(
                    <RadioGroup onChange={onRadioChange}>
                      <Radio value="view">跳转网页</Radio>
                      <Radio value="miniprogram">小程序</Radio>
                      <Radio value="click">发送消息</Radio>
                    </RadioGroup>
                  )}
                </FormItem>
                {formItemMap(channel, hasSelectSystemMenu && tcjsOpened).map(formItem => (
                  <FormItem label={formItem.label} key={formItem.paramKey}>
                    {getFieldDecorator(formItem.paramKey, {
                      rules: formItem.rules,
                    })(
                      <InputWithHttps
                        onFocus={() => {
                          setBuildInMenus({});
                          setTcjsOpened(false);
                        }}
                        disabled={formItem.disabled}
                        placeholder={formItem.placeholder}
                        allowClear
                        showAddBefore={channel === "view" && !formItem.disabled}
                      />
                    )}
                  </FormItem>
                ))}
                {channel !== "click" && (
                  <>
                    <FormItem {...tailFormItemLayout}>
                      <BuildInMenuSelect
                        channel={channel}
                        tcjsOpened={tcjsOpened}
                        buildInMenu={buildInMenus}
                        onDelete={onRemoveSelectMenu}
                        onShowClick={() => setVisible(true)}
                        currentMiniAppPlatform={currentMiniAppPlatform}
                      />
                    </FormItem>
                    <FormItem {...tailFormItemLayout}>
                      <Title level={4}>
                        <Text type="warning">
                          注1：请不要设置淘宝客相关链接及微信公众号不允许的链接，违规设置会有封号风险
                        </Text>
                      </Title>
                      <Title level={4}>
                        <Text type="warning">
                          注2：跳转的小程序需要和公众号先关联，
                          <a>查看详情</a>
                        </Text>
                      </Title>
                      <Title level={4}>
                        <Text type="warning">
                          注3：使用原始ID：gh_xxx无效；小程序页面顶部【...】处【复制链接】填入页面地址无效，
                          <a>查看详情</a>
                        </Text>
                      </Title>
                    </FormItem>
                  </>
                )}
              </>
            )}
            <FormItem {...tailFormItemLayout}>
              <Row type="flex" justify="center" gutter={[30, 0]} style={{ marginTop: 30 }}>
                <Col>
                  <Button onClick={onClose}>取消</Button>
                </Col>
                <Col>
                  <Button type="primary" onClick={onSubmit}>
                    确定
                  </Button>
                </Col>
                <Col>
                  <Popconfirm title="确定删除该菜单？" onConfirm={() => onDelete(selectMenuKey)}>
                    <Button type="danger" ghost>
                      删除
                    </Button>
                  </Popconfirm>
                </Col>
              </Row>
            </FormItem>
          </Form>
          <BuiltInMenuModal
            channel={channel}
            visible={visible}
            onClose={() => setVisible(false)}
            onSelect={value => onSystemMenuClick(value, platform)}
          />
        </>
      ) : (
        <SettingPublish />
      )}
    </div>
  );
};

export default connect(({ wxSettings, platform }) => ({
  showMenuSetting: wxSettings.showMenuSetting,
  selectMenuData: wxSettings.selectMenuData,
  currentMiniAppPlatform: wxSettings.currentMiniAppPlatform, // 当前用户绑定的小程序
  miniProgramMenuMap: wxSettings.miniProgramMenuMap,
  officialMenuMap: wxSettings.officialMenuMap,
  platformList: platform.platformList,
}))(
  Form.create({
    mapPropsToFields: props => {
      const { selectMenuData = {} } = props;
      const { name, url, appid, pagepath, key_word_content, type } = selectMenuData;
      const protocol = spliceURL(url, "protocol");
      return {
        name: Form.createFormField({
          value: name,
        }),
        url: Form.createFormField({
          value: protocol ? url : undefined,  // 当用户选择系统内置链接则不显示URL
        }),
        appid: Form.createFormField({
          value: appid,
        }),
        pagepath: Form.createFormField({
          value: pagepath,
        }),
        type: Form.createFormField({
          value: type || "view",
        }),
        key_word_content: Form.createFormField({
          value: key_word_content,
        }),
      };
    },
  })(MenuSetting)
);
